﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;

namespace SLBehaviourSystem
{
    public class BehaviourTreeEditorDrawer
    {
        static Texture DarkTask;
        static Texture DarkTaskSelected;
        static Texture DarkTaskIdentify;
        static Texture DarkTaskIdentifySelected;
        static Texture DarkTaskRunning;
        static Texture DarkTaskRunningSelected;
        static Texture ExecutionFailure;
        static Texture ExecutionSuccess;

        static bool isInit;

        private static void LoadTexture()
        {
            string path = "Assets/Plugins/BehaviourSystem/Editor/Res/";
            DarkTask = EditorWindowUtils.LoadTexture(path, "DarkTask.png");
            DarkTaskSelected = EditorWindowUtils.LoadTexture(path,"DarkTaskSelected.png");
            DarkTaskIdentify = EditorWindowUtils.LoadTexture(path, "DarkTaskIdentify.png");
            DarkTaskIdentifySelected = EditorWindowUtils.LoadTexture(path, "DarkTaskIdentifySelected.png");
            DarkTaskRunning = EditorWindowUtils.LoadTexture(path, "DarkTaskRunning.png");
            DarkTaskRunningSelected = EditorWindowUtils.LoadTexture(path, "DarkTaskRunningSelected.png");
            ExecutionFailure = EditorWindowUtils.LoadTexture(path, "ExecutionFailure.png");
            ExecutionSuccess = EditorWindowUtils.LoadTexture(path, "ExecutionSuccess.png");
        }

        public static void DrawNode(BehaviourEditorNode node, Vector2 offset)
        {
            if (!isInit)
            {
                isInit = true;
                LoadTexture();
            }
            BehaviourTreeNodeJsonData data = node.Data;

            node.rectInGraph.position = node.position - offset;
            BehaviourTreeEditorDrawer.DrawLineNode2ChildNode(node);
            Rect rectInGraph = node.rectInGraph;
            Rect signRect = new Rect(rectInGraph.position + rectInGraph.size - new Vector2(50, 50), new Vector2(50, 50));

            Rect nameRect = new Rect(rectInGraph.position + new Vector2(0, 20), rectInGraph.size);
            Rect childRect = new Rect(rectInGraph.position + new Vector2(0, 40), rectInGraph.size);
            Rect StateRect = new Rect(rectInGraph.position + new Vector2(0, 60), rectInGraph.size);
            Rect needWidthRect = new Rect(rectInGraph.position + new Vector2(0, 80), rectInGraph.size);
            Rect positionRect = new Rect(rectInGraph.position + new Vector2(0, 100), rectInGraph.size);
            Rect DataRect = new Rect(rectInGraph.position + new Vector2(0, 120), rectInGraph.size);


            if (node.Window != null)
            {
                if (node.Window.runTimeTree != null)
                {
                    BehaviourNodeBase runtimeNode = node.Window.runTimeTree.NodeDict[node.Data.Id];
                    switch (runtimeNode.CurNodeState)
                    {
                        case BehaviourNodeState.Idle:
                            if (node.Window.CurSelectNode != null && node.Data.Id == node.Window.CurSelectNode.Data.Id)
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskSelected, ScaleMode.StretchToFill);
                            }
                            else
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTask, ScaleMode.StretchToFill);
                            }
                            break;
                        case BehaviourNodeState.Running:
                            if (node.Window.CurSelectNode != null && node.Data.Id == node.Window.CurSelectNode.Data.Id)
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskRunningSelected, ScaleMode.StretchToFill);
                            }
                            else
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskRunning, ScaleMode.StretchToFill);
                            }
                            break;
                        case BehaviourNodeState.Success:
                            if (node.Window.CurSelectNode != null && node.Data.Id == node.Window.CurSelectNode.Data.Id)
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskIdentifySelected, ScaleMode.StretchToFill);
                            }
                            else
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskIdentify, ScaleMode.StretchToFill);
                            }
                            GUI.DrawTexture(signRect, ExecutionSuccess, ScaleMode.StretchToFill);
                            break;
                        case BehaviourNodeState.Failure:
                            if (node.Window.CurSelectNode != null && node.Data.Id == node.Window.CurSelectNode.Data.Id)
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskIdentifySelected, ScaleMode.StretchToFill);
                            }
                            else
                            {
                                GUI.DrawTexture(node.rectInGraph, DarkTaskIdentify, ScaleMode.StretchToFill);
                            }
                            GUI.DrawTexture(signRect, ExecutionFailure, ScaleMode.StretchToFill);

                            break;
                        default:
                            break;
                    }
                    GUI.Label(StateRect, string.Format("State :{0}", node.Window.runTimeTree.NodeDict[node.Data.Id].CurNodeState.ToString()));

                }
                else
                {
                    if (node.Window.CurSelectNode != null && node.Data.Id == node.Window.CurSelectNode.Data.Id)
                    {
                        GUI.DrawTexture(node.rectInGraph, DarkTaskSelected, ScaleMode.StretchToFill);
                    }
                    else
                    {
                        GUI.DrawTexture(node.rectInGraph, DarkTask, ScaleMode.StretchToFill);
                    }
                }

            }
            GUI.Label(rectInGraph, string.Format("节点Id:{0}", data.Id));
            GUI.Label(nameRect, string.Format("Name:{0}", data.Des));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.ChildIds.Count; i++)
            {
                sb.Append("   ");
                sb.Append(data.ChildIds[i]);
            }

            GUI.Label(childRect, string.Format("ChildIds:{0}", sb.ToString()));
            GUI.Label(needWidthRect, string.Format("NeedWidth:{0}", node.NeedWidth.ToString()));

            GUI.Label(positionRect, string.Format("position:{0}", node.position.ToString()));


            if (node.Data.Datas != null)
            {
                for (int i = 0; i < node.Data.Datas.Count; i++)
                {
                    DataRect.position += new Vector2(0, 20) * i;
                    GUI.Label(DataRect, string.Format("Datas {0}:{1}", i, node.Data.Datas[i].ToString()));
                }
            }

            for (int i = 0; i < node.Childs.Count; i++)
            {
                DrawNode(node.Childs[i], offset);
            }
        }

        public static void DrawLineNode2ChildNode(BehaviourEditorNode node)
        {
            Handles.color = Color.white;
            Rect rectInGraph = node.rectInGraph;
            BehaviourTreeNodeJsonData data = node.Data;

            if (node.Childs.Count == 0)
            {
                return;
            }
            if (node.Childs.Count == 1)
            {
                Handles.DrawLine(
                    new Vector2(rectInGraph.position.x + rectInGraph.width / 2, rectInGraph.position.y + rectInGraph.height),
                    new Vector2(node.Childs[0].rectInGraph.position.x + rectInGraph.width / 2, node.Childs[0].rectInGraph.position.y)
                    );
                return;
            }

            for (int i = 0; i < node.Childs.Count; i++)
            {
                Rect tempRect = node.Childs[i].rectInGraph;
                Vector3 childNodeverticalStartPoint = new Vector3(tempRect.x + tempRect.width / 2, tempRect.y);
                Vector3 childNodeverticalEndPoint = new Vector3(tempRect.x + tempRect.width / 2, tempRect.y - BehaciourEditorDefines.InteralY / 2);
                Handles.DrawLine(childNodeverticalStartPoint, childNodeverticalEndPoint);
            }

            //多个子节点时，绘制横线
            Rect startRect = node.Childs[0].rectInGraph;
            Rect endRect = node.Childs[node.Childs.Count - 1].rectInGraph;

            Vector3 horizontalStartPoint = new Vector3(startRect.x + startRect.width / 2, startRect.y - BehaciourEditorDefines.InteralY / 2, 0);
            Vector3 horizontalEndPoint = new Vector3(endRect.x + endRect.width / 2, endRect.y - BehaciourEditorDefines.InteralY / 2, 0);
            Handles.DrawLine(horizontalStartPoint, horizontalEndPoint);

            //父节点引出 竖线

            Vector3 parentNodeverticalStartPoint = new Vector3(rectInGraph.x + rectInGraph.width / 2, rectInGraph.y + rectInGraph.height);
            Vector3 parentNodeverticalEndPoint = new Vector3(rectInGraph.x + rectInGraph.width / 2, rectInGraph.y + rectInGraph.height + BehaciourEditorDefines.InteralY / 2);

            Handles.DrawLine(parentNodeverticalStartPoint, parentNodeverticalEndPoint);


        }


    }
}
